import CryptoJS from "crypto-js"

export class encryption {

    private static key = this.randomGenerate(16)  // AES密钥
    private static iv = this.randomGenerate(16);  // AES向量

    /**
     * 随机生成key和iv
     * @param length 指定随机KEY的长度
     * @private
     */
    private static randomGenerate(length: number) {
        const chars = ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E',
            'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z']
        if (!Number.isInteger(length) || length <= 0) { // 合法性校验
            return CryptoJS.enc.Utf8.parse('87654321ABCDEFGH');
        }
        let randomString = ''
        for (let i = 0; i < length; i++) {
            randomString += chars[Math.floor(Math.random() * chars.length)]
        }
        return CryptoJS.enc.Utf8.parse(randomString);
    }

    /**
     * AES加密数据
     * @param data
     */
    static encrypt(data: string) {
        const encrypted = CryptoJS.AES.encrypt(data, this.key, {
            iv: this.iv, // 这个参数我之前忘传了，使用CBC的时候一直会报错，所以千万不要忘记哦，如果创建成功，但是控制台一直报错什么undefined的呀，什么[0]啥的，就检查一下 是不是自己使用有问题
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7
        });
        return encrypted.toString()
    }

    /**
     * AES解密数据
     * @param data
     */
    static decrypt(data: string) {
        const decrypted = CryptoJS.AES.decrypt(data, this.key, {
            iv: this.iv,
            mode: CryptoJS.mode.ECB,
            padding: CryptoJS.pad.Pkcs7
        })
        return decrypted.toString(CryptoJS.enc.Utf8);
    }

    /**
     * 获取AES钥，需要发送给后端
     */
    static getKey() : string {
        return CryptoJS.enc.Utf8.stringify(this.key);
    }

    /**
     * 进行MD5操作，主要是针对登录密码
     * @param data
     */
    static md5(data: string) : string {
        return CryptoJS.MD5(data).toString();
    }
}
